"""
依赖注入模块

定义项目中所有的依赖注入函数：
- 数据库依赖
- 认证依赖
- 权限依赖
- 分页依赖
"""

from typing import Optional, Dict, Any
from fastapi import Depends, HTTPException, status, Header, Query

from .models import UserInDB
from . import database
from .utils import verify_token


# ========== 数据库依赖 ==========


def get_db() -> Any:
    """
    获取数据库连接（简化版）
    
    实际项目中应该：
    ```python
    from sqlalchemy.orm import Session
    
    def get_db():
        db = SessionLocal()
        try:
            yield db
        finally:
            db.close()
    ```
    
    Returns:
        数据库连接对象
    """
    # 在这个简化版本中，我们直接返回 database 模块
    return database


# ========== 认证依赖 ==========


def get_token(authorization: Optional[str] = Header(None)) -> str:
    """
    从请求头中获取 Token
    
    Args:
        authorization: Authorization 请求头，格式为 "Bearer <token>"
        
    Returns:
        解析后的 token
        
    Raises:
        HTTPException: 未提供认证信息
    """
    if not authorization:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="未提供认证信息",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 解析 "Bearer <token>" 格式
    parts = authorization.split()
    if len(parts) != 2 or parts[0].lower() != "bearer":
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="认证格式错误，应为: Bearer <token>",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    return parts[1]


def get_current_user(
    token: str = Depends(get_token),
    db: Any = Depends(get_db),
) -> UserInDB:
    """
    获取当前登录用户
    
    Args:
        token: 访问令牌
        db: 数据库连接
        
    Returns:
        当前用户对象
        
    Raises:
        HTTPException: Token 无效或用户不存在
    """
    # 验证 token 并获取用户名
    username = verify_token(token)
    if not username:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Token 无效或已过期",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 查询用户
    user = db.get_user_by_username(username)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户不存在",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 检查用户状态
    if not user.is_active:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="用户已被停用",
        )
    
    return user


def get_current_active_user(
    current_user: UserInDB = Depends(get_current_user),
) -> UserInDB:
    """
    获取当前活跃用户（额外检查）
    
    Args:
        current_user: 当前用户
        
    Returns:
        当前活跃用户对象
        
    Raises:
        HTTPException: 用户未激活
    """
    if not current_user.is_active:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="用户未激活",
        )
    return current_user


# ========== 权限依赖 ==========


def require_admin(
    current_user: UserInDB = Depends(get_current_user),
) -> UserInDB:
    """
    要求管理员权限
    
    Args:
        current_user: 当前用户
        
    Returns:
        当前管理员用户对象
        
    Raises:
        HTTPException: 权限不足
    """
    if current_user.role != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="需要管理员权限",
        )
    return current_user


def check_user_permission(user_id: int, current_user: UserInDB) -> bool:
    """
    检查用户是否有权限操作指定用户
    
    规则：
    - 管理员可以操作所有用户
    - 普通用户只能操作自己
    
    Args:
        user_id: 目标用户 ID
        current_user: 当前用户
        
    Returns:
        是否有权限
    """
    # 管理员有所有权限
    if current_user.role == "admin":
        return True
    
    # 普通用户只能操作自己
    return current_user.id == user_id


# ========== 分页依赖 ==========


class PaginationParams:
    """
    分页参数依赖类
    
    使用方法：
    ```python
    @app.get("/items")
    async def get_items(pagination: PaginationParams = Depends()):
        skip = pagination.skip
        limit = pagination.limit
        ...
    ```
    """
    
    def __init__(
        self,
        page: int = Query(1, ge=1, description="页码，从 1 开始"),
        page_size: int = Query(10, ge=1, le=100, description="每页数量，最多 100"),
    ):
        self.page = page
        self.page_size = page_size
        self.skip = (page - 1) * page_size
        self.limit = page_size
    
    def get_pagination_info(self, total: int) -> dict:
        """
        获取分页信息
        
        Args:
            total: 总记录数
            
        Returns:
            分页信息字典
        """
        total_pages = (total + self.page_size - 1) // self.page_size
        
        return {
            "page": self.page,
            "page_size": self.page_size,
            "total": total,
            "total_pages": total_pages,
            "has_prev": self.page > 1,
            "has_next": self.page < total_pages,
        }


# ========== 搜索筛选依赖 ==========


class UserFilterParams:
    """
    用户筛选参数依赖类
    """
    
    def __init__(
        self,
        search: Optional[str] = Query(None, description="搜索关键词（用户名或邮箱）"),
        role: Optional[str] = Query(None, pattern="^(user|admin)$", description="角色筛选"),
        is_active: Optional[bool] = Query(None, description="活跃状态筛选"),
    ):
        self.search = search
        self.role = role
        self.is_active = is_active

